package pl.cezary.butler.walili.client;

import pl.cezary.butler.walili.client.gui.GUI;
import pl.cezary.butler.walili.common.IServerFacadeRemote;
import pl.cezary.butler.walili.common.Task;
import java.awt.event.ActionEvent;
import java.io.IOException;
import java.rmi.RemoteException;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import pl.cezary.butler.walili.client.mime.DownloadingMimeTypeAction;
import pl.cezary.butler.walili.client.mime.MimeTypeAction;
import pl.cezary.butler.walili.client.mime.QueueDowloadAction;
import pl.cezary.butler.walili.common.Query;
import pl.cezary.butler.walili.common.TaskStatus;

// <editor-fold defaultstate="collapsed" desc=" UML Marker "> 
// #[regen=yes,id=DCE.4863859A-0D83-05B3-CD0D-49EB999FED2E]
// </editor-fold> 
public class TaskControler extends BaseControler {

    public static final String SEND = "wyslij";
    public static final String RETRY_FAILED = "retryF";
    public static final String FILL_MIME_TYPES = "fill_mime";
    public static final String FILL_DOWNLOADS = "fill_downloads";
    private static final Pattern ZADANIE_PATTERN = Pattern.compile("(f|ht)tp://([a-z0-9-_!?/]+\\.)+[a-z]{2,4}(/[a-z0-9-_!?&=%.]+)*/?", Pattern.CASE_INSENSITIVE);
    private static final Logger log = Logger.getLogger(TaskControler.class.getName());
    // <editor-fold defaultstate="collapsed" desc=" UML Marker "> 
    // #[regen=yes,id=DCE.14EB719B-4BE0-B503-5B80-7B45422B7642]
    // </editor-fold> 

    public TaskControler() {
    }

    @Override
    public void actionPerformed(ActionEvent arg0) {
        final String polecenie = arg0.getActionCommand();
        if (SEND.equals(polecenie)) {
            send();
        } else if (RETRY_FAILED.equals(polecenie)) {
            retry();
        } else if (FILL_MIME_TYPES.equals(polecenie)) {
            fillMimeTypes();
        } else if (FILL_DOWNLOADS.equals(polecenie)) {
            fillOldDownloads();
        } else {
            log.log(Level.SEVERE, "Unknown command sent", polecenie);
        }
    }

    private boolean validateTask(String zadanie) {
        Matcher zadanieMatcher = ZADANIE_PATTERN.matcher(zadanie);
        if (!zadanieMatcher.matches()) {
            log.log(Level.INFO, "Task url was deffective {0}", zadanie);
            getZrodloDanych().alert(GUI.getLocalized("taskCtl.wrong_task"));
            return false;
        }
        return true;
    }

    private void send() {
        final UserDataSource z = getZrodloDanych();
        try {
            final String zadanie = z.getZadanieCel();

            if (validateTask(zadanie)) {
                IServerFacadeRemote fasada = getFasada();
                if (fasada != null) {
                    fasada.sendTask(new Task(zadanie));
                    log.log(Level.INFO, "Task was sent : {0}", zadanie);
                } else {
                    z.alert(GUI.getLocalized("taskCtl.connection_error"));
                    log.log(Level.SEVERE, "Server facade error - there's no facade");
                }
            }
        } catch (RemoteException e) {
            log.log(Level.WARNING, "RMI error occured while trying to send task");
        }
    }

    @Override
    public void connectDataSource(UserDataSource z) {
        super.connectDataSource(z);
        z.podlaczKontrolerZadan(this);
    }

    private void retry() {
        try {
            getFasada().retryFailedTasks();
        } catch (RemoteException ex) {
            log.log(Level.SEVERE, null, ex);
        }
    }

    private void fillMimeTypes() {
        try {
            getFasada().fillMimeTypes();
        } catch (RemoteException ex) {
            log.log(Level.SEVERE, null, ex);
        }
    }

    private void fillOldDownloads() {
        final MimeTypeAction downloading = DownloaderApp.getContext().getBean(QueueDowloadAction.class);
        try {
            final Query query = new Query("%.mp3", null, TaskStatus.SUKCES, -1);
            final List<Task> tasks = getFasada().processQuery(query);
            for (Task task : tasks) {
                try {
                    downloading.process(task.getCelURL().openConnection());
                } catch (IOException ex) {
                    log.log(Level.SEVERE, null, ex);
                }
            }
        } catch (RemoteException ex) {
            Logger.getLogger(TaskControler.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}
